<template>
  <view class="ui-image-upload" :class="['is-' + dir]">
    <view class="ui-image-upload__control" v-if="!imageList || imageList.length<maxCount" @click="handleControlClick">
      <slot name="handle" :loading="uploading">
        <view class="ui-image-upload__control-main">
<!--
          <view class="ui-image-upload__control-icon"></view>
-->
          <view class="ui-image-upload__control-text">{{ '+'+ title}}</view>
        </view>
      </slot>
    </view>
    <template v-if="imageList && imageList.length && imageList.length>0 && showFileList">
      <view
          class="ui-image-upload__image"
          v-for="(item, index) in imageList"
          :key="index"
      >
        <slot name="image" :data="item">
          <ui-image
              :src="item.previewPath || item.path"
              :preview-src="item.path"
              width="80rpx"
              height="80rpx"
              :border="true"
          ></ui-image>
        </slot>
        <view class="ui-image-upload__loading" v-if="loadingMap[item.path]">
          <ui-icon name="loading" size="24px" color="#007aff"></ui-icon>
        </view>
        <view v-if="editable" class="ui-image-upload__image-remove" @click="handleRemoveImageClick(item, index)">
          <view class="ui-image-upload__image-remove-btn"></view>
        </view>
      </view>
    </template>
  </view>
</template>

<script>
import { uploadFile } from '@/apis/upload'
import { pathToBase64 } from 'image-tools'
import {uploadFileToTencentClound} from "../../apis/upload";

export default {
  name:"bi-image-upload-order",
  props: {
    value: {
      type: [String, Array]
    },
    mulitple: {
      type: Boolean,
      default: false
    },
    title: {
      type: String,
      default: '选择图片'
    },
    editable: {
      type: Boolean,
      default: true
    },
    dir: {
      type: String,
      default: 'horizon',
      validator (value) {
        return ['horizon', 'vertical'].includes(value)
      }
    },
    showFileList: {
      type: Boolean,
      default: true
    },
    upload: {
      type: Boolean,
      default: false
    },
    maxCount: {
      type: Number,
      default: 3
    },
    sourceType: {
      type: Array,
      default: () => ['album', 'camera']
    }
  },
  data () {
    return {
      imageList: [],
      loadingMap: {}
    }
  },
  computed: {
    uploadable () {
      if (!this.editable) {
        return false
      }
      if (!this.mulitple) {
        if (this.imageList && this.imageList.length) {
          return false
        }
      }
      return true
    },
    uploading () {
      return Object.keys(this.loadingMap).length > 0
    }
  },
  watch: {
    value () {
      if (!this.disableSyncImageList) {
        this.syncImageList()
      }
    }
  },
  created () {
    this.syncImageList()
  },
  methods: {
    handleControlClick () {
      if (!this.uploadable) {
        return
      }
      let imageCount=this.maxCount
      if(this.value){
        imageCount=this.maxCount-this.value.length
      }
      uni.chooseImage({
        sizeType: 'compressed',
        count:imageCount,
        sourceType: this.sourceType,
        extension: ['jpeg', 'jpg', 'png', 'gif', 'webp','mp4'],
        success: ({ tempFiles, tempFilePaths }) => {
          const files = tempFilePaths.map((v, i) => {
            return {
              path: v,
              file: tempFiles[i]
            }
          })
          files.forEach(file => {
            this.addFile(file)
          })
        },
        fail: (err) => {
          //error('选择图片失败')
        }
      })
    },
    handleRemoveImageClick (item, index) {
      this.imageList = this.imageList.filter((v, i) => i !== index)
      this.refreshValue()
    },
    syncImageList () {
      let imageList = []
      if (this.mulitple) {
        if (this.value) {
          imageList = this.value.map(v => {
            if (typeof v === 'string') {
              return {
                status: 'done',
                path: v
              }
            } else {
              return v
            }
          })
        } else {
          imageList = this.value || []
        }
      } else {
        if (this.value) {
          imageList = [this.value].map(v => {
            if (typeof v === 'string') {
              return {
                status: 'done',
                path: v
              }
            } else {
              return v
            }
          })
        } else {
          imageList = []
        }
      }
      this.imageList = imageList
    },
    addFile (file) {
      // #ifdef APP-PLUS
      pathToBase64(file.path).then(base64 => {
        file.previewPath = base64
        this._addFile(file)
      })
      // #endif

      // #ifndef APP-PLUS
      this._addFile(file)
      //#endif

    },
    _addFile (file) {
      if (!this.mulitple) {
        this.imageList = []
      }
      if (this.upload) {
        this.imageList.push(file)
        this.$set(this.loadingMap, file.path, true)
        uploadFileToTencentClound('aiduk',file.path).then((evt) => {
          file.path = evt.path
          file.status = 'done'
          this.refreshValue()
        }, () => {
          file.status = 'error'
        }).finally(() => {
          this.$delete(this.loadingMap, file.path)
        })
      } else {
        this.imageList.push(file)
        this.refreshValue()
      }
    },
    refreshValue () {
      if (this.upload) {
        let nextValue = this.imageList.filter(v => v.status === 'done').map(v => v.path)
        this.disableSyncImageList = true
        if (!this.mulitple) {
          nextValue = nextValue[0]
        }
        this.$emit('input', nextValue)
        this.$nextTick(() => {
          this.disableSyncImageList = false
        })
      } else {
        this.$emit('input', this.imageList)
      }
    }
  }
}
</script>

<style lang="scss">
.ui-image-upload {
  display: flex;
  &.is-vertical {
    flex-direction: column;
  }
  &.is-horizon {
    flex-direction: row;
    flex-wrap: wrap;
  }
}
.ui-image-upload__control-main{
  //width: 120rpx;
  width: 150rpx;
  height: 100rpx;
  color: #666;
  border: 1px solid #ddd;
  border-radius: 3px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.ui-image-upload__control-icon{
  display: block;
  width: 20rpx;
  height: 20rpx;
  position: relative;
  &:before{
    content: '';
    width: 2px;
    height: 18px;
    background-color: white;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }
  &:after{
    content: '';
    width: 30rpx;
    height: 5rpx;
    background-color: white;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }
}

.ui-image-upload__image{
  margin-bottom: 6px;
  margin-right: 6px;
  vertical-align: top;
}
.ui-image-upload__image {
  position: relative;
}
.ui-image-upload__image-remove{
  width: 30rpx;
  height: 30rpx;
  position: absolute;
  top: -12rpx;
  right: -12rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.ui-image-upload__image-remove-btn{
  width: 25rpx;
  height: 25rpx;
  background-color: #c00;
  border-radius: 50%;
  position: relative;
  transform: rotate(45deg);
  &:before{
    content: '';
    width: 10px;
    height: 1px;
    background-color: #fff;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
  &:after{
    content: '';
    width: 1px;
    height: 10px;
    background-color: #fff;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
}
.ui-image-upload__loading{
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, .8);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.ui-image-upload__control-text{
  font-size: 18rpx;
  margin-top: 8rpx;
  font-weight: bold;
}
.ui-image-upload__control-main{
  display: flex;
  width: 170rpx;
  height: 35rpx;
  color: white;
  border-radius: 15rpx;
  background-color: #EABC30;
  line-height: 20rpx;
  padding-bottom: 10rpx;
  margin-bottom: 15rpx;

}
</style>
